package org.datascooter.bundle;

import org.datascooter.bundle.attribute.PersistencePolicy;
import org.datascooter.exception.EntityNotMappedException;
import org.datascooter.generator.DSCounter;
import org.datascooter.impl.Condition;
import org.datascooter.impl.DataSnip;
import org.datascooter.impl.LogicValue;
import org.datascooter.utils.DBType;
import org.datascooter.utils.DSSettings;

/**
 * Utility class for setting up inner mappings
 * 
 * @author nemo
 * 
 */
public final class BundleUtils {

	private static final String ID2 = "ID";
	public static final String ID = "id";
	public static final String CREATED = "created";
	public static final int C512 = 512;
	public static final int C2048 = 2048;
	public static final int C1024 = 1024;
	public static final int C255 = 255;
	public static final int C36 = 36;
	public static final String CONTENT_CLASS2 = "content_class";
	public static final String CONTAINER_CLASS2 = "container_class";
	public static final String CONTENT_CLASS = "contentClass";
	public static final String CONTAINER_CLASS = "containerClass";
	public static final String CANUSED = "canUsed";
	public static final String DS_GLOBAL = "DS_GLOBAL";
	public static final String VALUE = "value";
	public static final String NAME = "name";
	private static final String DS_SEQUENCE = "DS_SEQUENCE";

	private BundleUtils() {
	}

	public static void prepareMapper() throws EntityNotMappedException, NoSuchMethodException {
		prepareSnipBundles();
		prepareCrossBundles();
		prepareSequences();
	}

	private static void prepareSnipBundles() throws EntityNotMappedException, NoSuchMethodException {
		BundleFactory.create(DataSnip.class.getName(), null, "ds_dsnip", DataSnip.class.getName(), !DSSettings.getCreateUtilityTables(), false);
		BundleFactory.setUseFieldAttributes(true);
		BundleFactory.createId(ID, ID2, DBType.CHAR, C36, 0, true, true, false);
		BundleFactory.createPersist(CREATED, CREATED, DBType.TIMESTAMP, 0, 0, true, true, true);
		BundleFactory.createPersist("entityName", "entity_name", DBType.STRING, C255, 0, true, true, false);
		BundleFactory.createPersist("snipType", "snip_type", DBType.STRING, C36, 0, true, true, false);
		BundleFactory.createReference("parentId", DataSnip.class.getName(), "parent_id", DBType.CHAR, C36, 0, true, true, true);
		BundleFactory.createPersist("sqlClause", "sql_clause", DBType.STRING, C1024, 0, true, true, true);
		BundleFactory.createPersist("extraAttribute", "extra_attribute", DBType.STRING, C255, 0, true, true, true);
		BundleFactory.createPersist("joinFromChild", "join_from_child", DBType.BOOLEAN, 0, 0, true, true, true);
		BundleFactory.createPersistChild("what", Condition.class.getName(), null, PersistencePolicy.ALL, false, false, "whatId", false);
		BundleFactory.createPersistChild("where", Condition.class.getName(), null, PersistencePolicy.ALL, false, false, "whereId", false);
		BundleFactory.createPersistChild("joinList", DataSnip.class.getName(), null, PersistencePolicy.ALL, false, false, null, false);
		BundleFactory.createPersistChild("fetchList", DataSnip.class.getName(), null, PersistencePolicy.ALL, false, false, null, false);
		// bundle.createReference("whatId", Condition.class.getName(), "what_id", DBType.CHAR, _36, 0, true, true, true);
		// bundle.createReference("whereId", Condition.class.getName(), "where_id", DBType.CHAR, _36, 0, true, true, true);
		BundleFactory.createPersist("whatId", "what_id", DBType.CHAR, C36, 0, true, true, true);
		BundleFactory.createPersist("whereId", "where_id", DBType.CHAR, C36, 0, true, true, true);
		BundleFactory.completeSilent();
		//
		BundleFactory.create(Condition.class.getName(), null, "ds_condition", Condition.class.getName(), !DSSettings.getCreateUtilityTables(), false);
		BundleFactory.setUseFieldAttributes(true);
		BundleFactory.createId(ID, ID2, DBType.CHAR, C36, 0, true, true, false);
		BundleFactory.createReference("snipId", DataSnip.class.getName(), "snip_id", DBType.CHAR, C36, 0, true, true, false);
		BundleFactory.createPersist("isWhere", "is_where", DBType.BOOLEAN, 0, 0, true, true, true);
		BundleFactory.createPersist("operation", "operation_str", DBType.STRING, C36, 0, true, true, false);
		BundleFactory.createReference("parentId", Condition.class.getName(), "parent_id", DBType.CHAR, C36, 0, true, true, true);
		BundleFactory.createPersistChild("childList", Condition.class.getName(), null, PersistencePolicy.ALL, false, false, null, false);
		BundleFactory.createPersistChild("valueList", LogicValue.class.getName(), null, PersistencePolicy.ALL, false, false, null, false);
		BundleFactory.completeSilent();
		//
		BundleFactory.create(LogicValue.class.getName(), null, "ds_logic_value", LogicValue.class.getName(), !DSSettings.getCreateUtilityTables(), false);
		BundleFactory.setUseFieldAttributes(true);
		BundleFactory.createId(ID, ID2, DBType.CHAR, C36, 0, true, true, false);
		BundleFactory.createReference("conditionId", Condition.class.getName(), "condition_id", DBType.CHAR, C36, 0, true, true, false);
		BundleFactory.createPersist("attribute", "simple_attribute", DBType.STRING, C255, 0, true, true, false);
		BundleFactory.createPersist("constraint", "constraint_str", DBType.STRING, C36, 0, true, true, false);
		BundleFactory.createPersist("valueClass", "value_class", DBType.STRING, C1024, 0, true, true, true);
		BundleFactory.createPersist("valueString", "value_string", DBType.STRING, C2048, 0, true, true, true);
		BundleFactory.completeSilent();
	}

	private static void prepareCrossBundles() throws SecurityException, NoSuchMethodException, EntityNotMappedException {
		BundleFactory.create(CrossTable.class.getName(), null, "ds_cross_table", CrossTable.class.getName(), !DSSettings.getCreateUtilityTables(), false);
		BundleFactory.createId(ID, ID2, DBType.CHAR, C36, 0, true, true, false);
		BundleFactory.addIndex("CROSS_TAB_1", null, BundleFactory.createPersist(CONTAINER_CLASS, CONTAINER_CLASS2, DBType.STRING, C1024, 0, true, true, false));
		BundleFactory.addIndex("CROSS_TAB_2", null, BundleFactory.createPersist(CONTENT_CLASS, CONTENT_CLASS2, DBType.STRING, C1024, 0, true, true, false));
		BundleFactory.createPersist("containerAttribute", "container_attribute", DBType.STRING, C1024, 0, true, true, false);
		BundleFactory.createPersist("tableName", "table_name", DBType.STRING, C512, 0, true, true, false);
		BundleFactory.createPersist("mapKey", "map_key", DBType.STRING, C36, 0, true, true, true);
		BundleFactory.completeSilent();
		//
		BundleFactory.create(CrossData.class.getName(), null, null, CrossData.class.getName(), true, false);
		BundleFactory.addIndex("CONTAINER_TAB_1", null, BundleFactory.createPersist("containerId", "container_id", null, 0, 0, true, true, false));
		BundleFactory.addIndex("CONTENT_TAB_2", null, BundleFactory.createPersist("contentId", "content_id", null, 0, 0, true, true, false));
		BundleFactory.completeSilent();
	}

	private static void prepareSequences() throws SecurityException, NoSuchMethodException, EntityNotMappedException {
		BundleFactory.create(DSCounter.class.getName(), null, DS_SEQUENCE, DSCounter.class.getName(), false, false);
		BundleFactory.createId(ID, ID2, DBType.CHAR, C36, 0, true, true, false);
		BundleFactory.createPersist(NAME, NAME, DBType.STRING, C512, 0, true, true, false);
		BundleFactory.createPersist(VALUE, VALUE, DBType.LONG, 0, 0, true, true, false);
		BundleFactory.createPersist(CANUSED, CANUSED, DBType.LONG, 0, 0, true, true, false);
		BundleFactory.completeSilent();
	}
}
